home *** CD-ROM | disk | FTP | other *** search
- UNIT STR_STF;
- {**------------------------------------------------**}
- {** STRING Library OPERATIONS **}
- {** Version 1.2 **}
- {** Added Pos_Reverse **}
- {** Version 1.1 (sped-ups) **}
- {** (delete_duplicate_Chars_in_str) **}
- {** Added Int_To_Str_Zero_Fill **}
- {**------------------------------------------------**}
-
- {$O-,F+}
-
- INTERFACE
- {**************************************************************}
- {* Trim removes leading/trailing blanks. *}
- {* *}
- {**************************************************************}
- FUNCTION TRIM (Str : string) : string;
-
- FUNCTION TRIM_Leading_Only (Str : string) : string;
- FUNCTION TRIM_Trailing_Only (Str : string) : string;
- FUNCTION TRIM_Quotes (Str : string) : string;
-
- {**************************************************************}
- {* Right_Justify adds leading blanks. *}
- {* NOTE: does not handle cases when *}
- {* Size_To_Be < ACTUAL NUMBER OF CHARACTERS *}
- {**************************************************************}
- FUNCTION Right_Justify (Str : string; Size_To_Be : integer) : string;
-
- {***************************************************************}
- {* Center_Str centers the characters in the string based *}
- {* upon the size/midpoint specified. *}
- {***************************************************************}
- FUNCTION Center_Str (Str : string; Output_Size : integer) : string;
-
- {**************************************************************}
- {* Change_Case changes the case of the string to UPPER. *}
- {* *}
- {**************************************************************}
- FUNCTION CHANGE_CASE (Str : string) : string;
- FUNCTION Lower_Case (Str : string) : string;
-
- {**************************************************************}
- {* Int_To_Str returns the number converted into ascii chars. *}
- {* *}
- {**************************************************************}
- FUNCTION Int_To_Str (Num : LongInt) : string;
- FUNCTION Int_To_Str_Zero_Fill (Num : LongInt; Fill : byte) : string;
- FUNCTION Int_Num_Digits (Num : LongInt) : integer;
-
- {**************************************************************}
- {* Pos_Reverse returns the last occurance of the string *}
- {* just before the specified start pos! *}
- {**************************************************************}
- FUNCTION Pos_Reverse (Str : string;
- Delimiter : string;
- Start_At : integer) : integer;
-
- {**************************************************************}
- {* Find_Char returns the position of the char *}
- {* *}
- {**************************************************************}
- FUNCTION Find_Char (Str : string;
- Char_Is : char;
- Start_At : integer) : INTEGER;
-
- {**************************************************************}
- {* Delete_The_Char delete all occurances of the char *}
- {* *}
- {**************************************************************}
- FUNCTION Delete_The_Char
- (Str : string;
- Char_Is : char) : string;
-
- {**************************************************************}
- {* Replace_Str_Into inserts the small string into the *}
- {* org_str at the position specified *}
- {**************************************************************}
- FUNCTION Replace_Str_Into (Org_Str : String;
- Small_Str : string;
- Start, Stop : integer) : string;
-
- {**************************************************************}
- {* procedure Get_Word_Around_Position *}
- {* returns the word based AROUND the position specified *}
- {* Searches for blanks around the start_pos *}
- {* looking left then right. *}
- {**************************************************************}
- function Get_Word_Around_Position
- (Str : string;
- Start_Pos : integer;
- Leftmost_Char_Boundry : integer;
- Rightmost_Char_Boundry : integer;
- VAR Found_Left_Pos : integer;
- VAR Found_Word_Size : integer) : string;
-
- {**************************************************************}
- {* returns a string with duplicate chars deleted. *}
- {**************************************************************}
- function Delete_Duplicate_Chars_In_Str (Str : string;
- Limit_In_A_Row : byte): string;
-
- {**************************************************************}
- {* returns a string filled with the character specified *}
- {**************************************************************}
- function Fill_String(Len : Byte; Ch : Char) : String;
-
- {**************************************************************}
- {* Truncates a string to a specified length *}
- {**************************************************************}
- function Trunc_Str(TString : String; Len : Byte) : String;
-
- {**************************************************************}
- {* Pads a string to a specified length with a specified character }
- {**************************************************************}
- function Pad_Char(PString : String; Ch : Char; Len : Byte) : String;
-
-
- {**************************************************************}
- {* Left-justify a string within a certain width *}
- {**************************************************************}
- function Left_Justify_Str (S : String; Width : Byte) : String;
-
-
- {**************************************************************}
- {* Note that "Count" is the number of *WORDS* to fill. *}
- {* So e.g. you'd use *}
- {* "FillWord(My_Int_Array, SizeOf(My_Int_Array) DIV 2, 1);" *}
- {* by Neil Rubenking *}
- {**************************************************************}
- PROCEDURE FillWord (VAR Dest; Count, What : Word);
-
-
- {**************************************************************}
- {**************************************************************}
- {**************************************************************}
- IMPLEMENTATION
-
- {**************************************************************************}
- function Min(N1, N2 : Longint) : Longint;
- { Returns the smaller of two numbers }
- begin
- if N1 <= N2 then
- Min := N1
- else
- Min := N2;
- end; { Min }
-
- (*
- {**************************************************************************}
- function Max(N1, N2 : Longint) : Longint;
- { Returns the larger of two numbers }
- begin
- if N1 >= N2 then
- Max := N1
- else
- Max := N2;
- end; { Max }
- *)
-
- {**************************************************************}
- {* returns a string filled with the character specified *}
- {**************************************************************}
- function Fill_String(Len : Byte; Ch : Char) : String;
- var
- S : String;
- begin
- IF (Len > 0) THEN
- BEGIN
- S[0] := Chr(Len);
- FillChar(S[1], Len, Ch);
- Fill_String := S;
- END
- ELSE Fill_String := '';
- end; { FillString }
-
- {**************************************************************}
- {* Truncates a string to a specified length *}
- {**************************************************************}
- function Trunc_Str(TString : String; Len : Byte) : String;
- begin
- if (Length(TString) > Len) then
- begin
- {Delete(TString, Succ(Len), Length(TString) - Len);}
- {Move(TString[Succ(Len)+(LENGTH(TString)-Len)], TString[Succ(Len)],
- Succ(Length(TString)) - Succ(Len) - Length(TString) - Len));}
- Move(TString[LENGTH(TString)+1], TString[Succ(Len)], 2*Len);
- Dec(TString[0], Length(TString) - Len);
- end;
- Str_Stf.Trunc_Str := TString;
- end; { TruncStr }
-
- {**************************************************************}
- {* Pads a string to a specified length with a specified character }
- {**************************************************************}
- function Pad_Char(PString : String; Ch : Char; Len : Byte) : String;
- var
- CurrLen : Byte;
- begin
- CurrLen := Min(Length(PString), Len);
- PString[0] := Chr(Len);
- FillChar(PString[Succ(CurrLen)], Len - CurrLen, Ch);
- Pad_Char := PString;
- end; { PadChar }
-
- {**************************************************************}
- {* Left-justify a string within a certain width *}
- {**************************************************************}
- function Left_Justify_Str(S : String; Width : Byte) : String;
- begin
- Left_Justify_Str := Str_Stf.Pad_Char(S, ' ', Width);
- end; { Left_Justify_Str }
-
- {**************************************************************}
- {* Trim removes leading/trailing blanks. *}
- {* *}
- {**************************************************************}
- FUNCTION TRIM (Str : string) : string;
- VAR
- i : integer;
- BEGIN
- i := 1;
- WHILE ((i < LENGTH(Str)) and (Str[i] = ' '))
- DO INC(i);
-
- IF (i > 1) THEN
- BEGIN
- {Str := COPY (Str, i, Length(Str));}
- Move (Str[i], Str[1], Succ(LENGTH(Str))-i);
- DEC (Str[0], pred(i));
- END;
-
- WHILE (Str[LENGTH(str)] = ' ')
- DO DEC (Str[0]);
-
- Trim := Str;
- END; {trim}
-
- {**************************************************************}
- {* Trim_Lead removes leading blanks. *}
- {* *}
- {**************************************************************}
- FUNCTION TRIM_Leading_Only (Str : string) : string;
- VAR
- i : integer;
- BEGIN
- i := 1;
- WHILE ((i < LENGTH(Str)) and (Str[i] = ' '))
- DO INC(i);
-
- IF (i > 1) THEN
- BEGIN
- {Str := COPY (Str, i, Length(Str));}
- Move (Str[i], Str[1], Succ(LENGTH(Str))-i);
- DEC (Str[0], pred(i));
- END;
-
- Trim_Leading_Only := Str;
- END; {trim_leading_Only}
-
- {***************************************************************}
- FUNCTION TRIM_Trailing_Only (Str : string) : string;
- BEGIN
- WHILE (Str[LENGTH(str)] = ' ')
- DO DEC (Str[0]);
-
- Trim_Trailing_Only := Str;
- END; {trim}
-
- {***************************************************************}
- {*------------------------------------------------------*}
- {* Trim off any lead/trail quotes! *}
- {*------------------------------------------------------*}
- FUNCTION TRIM_Quotes (Str : string) : string;
- begin
- IF ((LENGTH(Str) > 0) and (Str[1] = '"')) THEN
- BEGIN
- Move (Str[2], Str[1], pred(LENGTH(Str)));
- DEC (Str[0]);
- IF (Str[LENGTH(Str)] = '"')
- THEN DEC(Str[0]);
- END; {if}
- Trim_Quotes := Str;
- end; {Trim_Quotes}
-
- {***************************************************************}
- {* Right_Justify adds leading blanks. *}
- {* NOTE: does not handle cases when *}
- {* Size_To_Be < ACTUAL NUMBER OF CHARACTERS *}
- {***************************************************************}
- FUNCTION Right_Justify (Str : string; Size_To_Be : integer) : string;
- VAR
- Temp_Str : string;
- BEGIN
- Temp_Str := TRIM (Str); {to assure proper length--and NON-BLANK}
- Right_Justify := Str_Stf.Left_Justify_Str
- ('', Size_To_Be - Length(Str)) + Str;
-
- { WHILE ((LENGTH(Temp_Str) > 0) AND
- ( (Size_To_Be > LENGTH (Temp_Str)) OR
- (Temp_Str[Size_To_Be] = ' ') ) )
- DO Temp_Str := ' '+ COPY (Temp_Str, 1, Size_To_Be-1);
- Right_Justify := Temp_Str;}
-
- END; {right_justify}
-
- {***************************************************************}
- {* Center_Str centers the characters in the string based *}
- {* upon the size/midpoint specified. *}
- {***************************************************************}
- FUNCTION Center_Str (Str : string; Output_Size : integer) : string;
- VAR
- Ret_Str : string;
- Size : integer;
- BEGIN
- { blank out returning string}
- Ret_Str := Str_Stf.Fill_String(Output_Size, ' ');
- {FillChar (Ret_Str, output_size, ' ');
- Ret_Str[0] := chr(Output_Size);}
-
- Str := TRIM (Str);
- Size := LENGTH (Str);
- IF (Output_Size <= Size)
- THEN Ret_Str := Str
- ELSE
- BEGIN
- Insert (Str, Ret_Str, (((Output_Size - Size) div 2)+1));
- Ret_Str := COPY (Ret_Str, 1, OutPut_Size);
- END;
- Center_Str := Ret_Str;
- END; {center_str}
-
- {**************************************************************}
- {* Change_Case changes the case of the string to UPPER. *}
- {* *}
- {**************************************************************}
- FUNCTION Change_Case (Str : string) : string;
- var
- i : integer;
- BEGIN
- for i := 1 to LENGTH (Str)
- do Str[i] := UpCase(Str[i]);
- Change_Case := Str;
- END; {change_case}
-
- {**************************************************************}
- FUNCTION Lower_Case (Str : string) : string;
- var
- i : integer;
- BEGIN
- for i := 1 to LENGTH (Str)
- do IF ((ORD (Str[i]) >= 65) and (ORD(Str[i]) <= 90))
- THEN Str[i] := CHR(ORD(Str[i])+32);
- Lower_Case := Str;
- END; {lower_case}
-
- {**************************************************************}
- {* Int_To_Str returns the number converted into ascii chars. *}
- {* *}
- {**************************************************************}
- FUNCTION Int_To_Str (Num : LongInt) : string;
- var
- Temp_Str : string;
- BEGIN
- STR(Num, Temp_Str);
- Int_To_Str := Temp_Str;
- END; {int_to_str}
-
- FUNCTION Int_To_Str_Zero_Fill (Num : LongInt; Fill : byte) : string;
- var
- Temp_Str : string;
- Len : byte;
- BEGIN
- STR(Num, Temp_Str);
- Len := LENGTH(Temp_Str);
- IF (Len < Fill)
- THEN Temp_Str := Fill_String(Fill-Len, '0')+Temp_Str;
- Int_To_Str_Zero_Fill := Temp_Str;
- END; {int_to_str_zero_fill}
-
- FUNCTION Int_Num_Digits (Num : LongInt) : integer;
- var
- Tens, Digits : Integer;
- BEGIN
- IF (Num = 0)
- THEN Int_Num_Digits := 1
- ELSE
- BEGIN
- Tens := 1;
- Digits := 1;
- WHILE ((Num DIV Tens) <> 0) DO
- BEGIN
- INC (Digits);
- Tens := Tens * 10;
- END; {while}
-
- IF (Digits > 1)
- THEN DEC (Digits);
- Int_Num_Digits := Digits;
- END; {if}
-
- END; {int_num_digits}
-
- {**************************************************************}
- {* Pos_Reverse returns the last occurance of the string *}
- {* just before the specified start pos! *}
- {**************************************************************}
- FUNCTION Pos_Reverse (Str : string;
- Delimiter : string;
- Start_At : integer) : integer;
- VAR
- Temp_Str : string;
- Found_Pos, Found_Pos_0 : integer;
- BEGIN
- Temp_Str := COPY(Str, 1, Start_At); {dont use move since ?start_at <length?}
- Found_Pos_0 := 0;
- REPEAT
- Found_Pos := POS (Delimiter, Temp_Str);
- IF (Found_Pos <> 0) THEN
- BEGIN
- Found_Pos_0 := Found_Pos_0+Found_Pos;
- {Temp_Str := COPY(Temp_Str, Found_Pos+1, LENGTH(Temp_Str));}
- Move (Temp_Str[Found_Pos+1], Temp_Str[1], LENGTH(Str)-Found_Pos+2);
- DEC (Temp_Str[0], Found_Pos);
- END;
- UNTIL (Found_Pos = 0);
- Pos_Reverse := Found_Pos_0;
- END; {pos_reverse}
-
- {**************************************************************}
- {* Find_Char returns the position of the char *}
- {* *}
- {**************************************************************}
- FUNCTION Find_Char (Str : string;
- Char_Is : char;
- Start_At : integer) : INTEGER;
- VAR
- Loc : integer;
- BEGIN
- Loc := POS (Char_Is, COPY(Str, Start_At, LENGTH(STR)));
- IF (Loc <> 0)
- THEN Loc := Loc + Start_At -1;
- Find_Char := Loc;
- END; {function Find_Char}
-
- {**************************************************************}
- {* Delete_The_Char delete all occurances of the char *}
- {* *}
- {**************************************************************}
- FUNCTION Delete_The_Char (Str : string;
- Char_Is : char) : string;
- VAR
- Loc : integer;
- BEGIN
- Loc := 0;
- REPEAT
- Loc := POS (Char_Is, Str);
- IF (Loc <> 0) THEN
- BEGIN
- {DELETE (Str, Loc, 1);}
- Move(Str[Succ(Loc)], Str[Loc], Length(Str)-Loc);
- Dec(Str[0]);
- END;
- UNTIL (Loc = 0);
-
- Delete_The_Char := STR;
- END; {function Delete_The_Char}
-
- {**************************************************************}
- {* Replace_Str_Into inserts the small string into the *}
- {* org_str at the position specified *}
- {**************************************************************}
- FUNCTION Replace_Str_Into (Org_Str : String;
- Small_Str : string;
- Start, Stop : integer) : string;
- var
- Temp_Small_Str : string;
- begin
- IF (Start = 0)
- THEN Start := 1;
-
- IF (LENGTH(Small_Str) >= (Stop-Start+1))
- THEN Temp_Small_Str := Small_Str
- ELSE Temp_Small_Str := Small_Str +
- Fill_String ( (Stop-Start+1-LENGTH(Small_Str)), ' ');
- IF (Start > 1)
- THEN Replace_Str_Into := Copy (Org_Str, 1, (Start -1)) +
- Copy (Temp_Small_Str, 1, (Stop-Start+1))+
- Copy (Org_Str, (Stop+1) , LENGTH(Org_Str))
- ELSE Replace_Str_Into := Copy (Temp_Small_Str, 1, (Stop-Start+1)) +
- Copy (Org_Str, Stop+1, LENGTH(Org_Str));
- end; {Replace_Str_into}
-
- {**************************************************************}
- {* procedure Get_Word_Around_Position *}
- {* returns the word based AROUND the position specified *}
- {* Searches for blanks around the start_pos *}
- {* looking left then right. *}
- {**************************************************************}
- function Get_Word_Around_Position
- (Str : string;
- Start_Pos : integer;
- Leftmost_Char_Boundry : integer;
- Rightmost_Char_Boundry : integer;
- VAR Found_Left_Pos : integer;
- VAR Found_Word_Size : integer) : string;
- var
- adjust : integer;
-
- begin
- IF ((Start_Pos <= LENGTH(Str))) THEN
- BEGIN
- Get_Word_Around_Position := Str[Start_Pos];
- Found_Left_Pos := Start_Pos;
- Found_Word_Size := 1;
- END
-
- ELSE {* Bad Params! *}
- BEGIN
- Get_Word_Around_Position := ' ';
- Found_Left_Pos := 0;
- Found_Word_Size := 0;
- Exit;
- END;
-
- if (Str[Start_Pos] <> ' ') then
- begin
- {************************************************}
- {* FIRST: find left-most position *}
- {************************************************}
- adjust := Start_Pos -1;
- while ((adjust >= leftmost_char_boundry) and
- (Str[adjust] <> ' '))
- do adjust := adjust - 1;
- if ((adjust = leftmost_char_boundry) and (Str[adjust] <> ' '))
- then Found_Left_Pos := adjust
- else Found_Left_Pos := adjust +1;
-
- {************************************************}
- {* find right-most position *}
- {************************************************}
- adjust := Start_Pos +1;
- while ((adjust <= Rightmost_Char_Boundry) and
- (Str[adjust] <> ' '))
- do adjust := adjust + 1;
-
- if ((adjust = Rightmost_char_boundry) and (Str[adjust] <> ' '))
- then Found_Word_Size := adjust - Found_Left_Pos +1
- else Found_Word_Size := adjust - Found_Left_Pos;
-
- Get_Word_Around_Position := Copy (Str, Found_Left_Pos, Found_Word_Size);
-
- end; {if}
-
- end; {get_word_around_position}
-
- {**************************************************************}
- {* returns a string with duplicate chars deleted. *}
- {**************************************************************}
- function Delete_Duplicate_Chars_In_Str (Str : string;
- Limit_In_A_Row : byte) : string;
- var
- Curr_Pos : integer;
- i : integer;
- Same_Chars : boolean;
- begin
-
- IF (Limit_In_A_Row = 1) THEN {* must catch or infinite loop *}
- BEGIN
- Delete_Duplicate_Chars_In_Str := '';
- exit;
- END;
-
- Curr_Pos := 1;
- WHILE ((Curr_Pos+Limit_In_A_Row-1) <= LENGTH(Str)) DO
- BEGIN
-
- {*---------------------------------------*}
- {* Quickly look for at least 2 in a row! *}
- {*---------------------------------------*}
- WHILE (((Curr_Pos+Limit_In_A_Row-1) <= LENGTH(Str)) AND
- (Str[Curr_Pos] <> Str[Succ(Curr_Pos)]))
- DO INC(Curr_Pos);
-
- IF ((Curr_Pos+Limit_In_A_Row-1) <= LENGTH(Str)) THEN
- BEGIN
- i := Curr_Pos+1;
- Same_Chars := TRUE;
- WHILE ((Same_Chars) and (i <= (Curr_Pos+Limit_In_A_Row-1)))
- DO IF (Str[Curr_Pos] <> Str[i])
- THEN Same_Chars := FALSE
- ELSE INC(i);
-
- IF (Same_Chars) THEN
- BEGIN
- Move(Str[Curr_Pos+Limit_In_A_Row-1], Str[Curr_Pos],
- Length(Str)-(Curr_Pos+Limit_In_A_Row-2));
- Dec(Str[0],Pred(Limit_In_A_Row));
- END
- ELSE Inc(Curr_Pos);
- END; {if}
- END; {while}
-
- Delete_Duplicate_Chars_In_Str := Str;
- end; {delete_duplicate_chars_in_str}
-
- {*
- Note that "Count" is the number of *WORDS* to fill. So e.g. you'd
- use "FillWord(My_Int_Array, SizeOf(My_Int_Array) DIV 2, 1);"
- by Neil Rubenking *}
- {**************************************************************}
- PROCEDURE FillWord(VAR Dest; Count, What : Word); Assembler;
- ASM
- LES DI, Dest {ES:DI points to destination}
- MOV CX, Count {count in CX}
- MOV AX, What {word to fill with in AX}
- CLD {forward direction}
- REP STOSW {perform the fill}
- END; {fillWord}
-
- END. {unit str_stf}